package com.tiyende.kash.loop.weight.city

import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.tiyende.kash.loop.weight.city.EntityWrapper
import com.tiyende.kash.loop.weight.city.IndexableEntity
import com.tiyende.kash.loop.weight.city.data.DataObservable
import com.tiyende.kash.loop.weight.city.data.DataObserver

abstract class IndexableAdapter<T : IndexableEntity?> {

    companion object{
        const val TYPE_ALL = 0
        const val TYPE_CLICK_TITLE = 1
        const val TYPE_CLICK_CONTENT = 2
        const val TYPE_LONG_CLICK_TITLE = 3
        const val TYPE_LONG_CLICK_CONTENT = 4
    }

    private val mDataSetObservable = DataObservable()

    private var mDatas: List<T>? = null

    private var mCallback: IndexCallback<T>? = null
    private var mTitleClickListener: OnItemTitleClickListener? = null
    private var mContentClickListener: OnItemContentClickListener<*>? = null
    private var mTitleLongClickListener: OnItemTitleLongClickListener? = null
    private var mContentLongClickListener: OnItemContentLongClickListener<*>? = null

    abstract fun onCreateTitleViewHolder(parent: ViewGroup?): RecyclerView.ViewHolder?

    abstract fun onCreateContentViewHolder(parent: ViewGroup?): RecyclerView.ViewHolder?

    abstract fun onBindTitleViewHolder(holder: RecyclerView.ViewHolder?, indexTitle: String?)

    abstract fun onBindContentViewHolder(holder: RecyclerView.ViewHolder?, entity: T)

    fun setDatas(datas: List<T>?) {
        setDatas(datas, null)
    }

    /**
     * @param callback Register a callback to be invoked when this datas is processed.
     */
    fun setDatas(datas: List<T>?, callback: IndexCallback<T>?) {
        mCallback = callback
        mDatas = datas
        notifyInited()
    }

    /**
     * set Index-ItemView click listener
     */
    fun setOnItemTitleClickListener(listener: OnItemTitleClickListener?) {
        mTitleClickListener = listener
        notifySetListener(TYPE_CLICK_TITLE)
    }

    /**
     * set Content-ItemView click listener
     */
    fun setOnItemContentClickListener(listener: OnItemContentClickListener<T>?) {
        mContentClickListener = listener
        notifySetListener(TYPE_CLICK_CONTENT)
    }

    /**
     * set Index-ItemView longClick listener
     */
    fun setOnItemTitleLongClickListener(listener: OnItemTitleLongClickListener?) {
        mTitleLongClickListener = listener
        notifySetListener(TYPE_LONG_CLICK_TITLE)
    }

    /**
     * set Content-ItemView longClick listener
     */
    fun setOnItemContentLongClickListener(listener: OnItemContentLongClickListener<T>?) {
        mContentLongClickListener = listener
        notifySetListener(TYPE_LONG_CLICK_CONTENT)
    }

    /**
     * Notifies the attached observers that the underlying data has been changed
     * and any View reflecting the data set should refresh itself.
     */
    fun notifyDataSetChanged() {
        mDataSetObservable.notifyInited()
//        mDataSetObservable.notifyChanged();
    }

    private fun notifyInited() {
        mDataSetObservable.notifyInited()
    }

    private fun notifySetListener(type: Int) {
        mDataSetObservable.notifySetListener(type)
    }

    fun getItems(): List<T>? {
        return mDatas
    }

    fun getIndexCallback(): IndexCallback<T>? {
        return mCallback
    }

    fun getOnItemTitleClickListener(): OnItemTitleClickListener? {
        return mTitleClickListener
    }

    fun getOnItemTitleLongClickListener(): OnItemTitleLongClickListener? {
        return mTitleLongClickListener
    }

    fun getOnItemContentClickListener(): OnItemContentClickListener<*>? {
        return mContentClickListener
    }

    fun getOnItemContentLongClickListener(): OnItemContentLongClickListener<*>? {
        return mContentLongClickListener
    }

    fun registerDataSetObserver(observer: DataObserver) {
        mDataSetObservable.registerObserver(observer)
    }

    fun unregisterDataSetObserver(observer: DataObserver) {
        mDataSetObservable.unregisterObserver(observer)
    }


    interface IndexCallback<T> {
        fun onFinished(datas: List<EntityWrapper<T>>)
    }


    interface OnItemTitleClickListener {
        fun onItemClick(v: View?, currentPosition: Int, indexTitle: String?)
    }


    interface OnItemContentClickListener<T> {
        fun onItemClick(v: View?, originalPosition: Int, currentPosition: Int, entity: T)
    }


    interface OnItemTitleLongClickListener {
        fun onItemLongClick(v: View?, currentPosition: Int, indexTitle: String?): Boolean
    }


    interface OnItemContentLongClickListener<T> {
        fun onItemLongClick(v: View?, originalPosition: Int, currentPosition: Int, entity: T): Boolean
    }

}